﻿using HCMS.CommonDtos;
using HCMS.Const;
using HCMS.Entities.Manage;
using HCMS.Extensions;
using HCMS.IServices.Manage;
using HCMS.Utils;
using HCMS.Web.Manage.Filter;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace HCMS.Web.Manage.Controllers
{
    /// <summary>
    /// 登录认证
    /// </summary>
    public class AuthController : BaseController
    {
        private readonly IAdminAppService adminAppService;
        private readonly IAdminRoleAppService adminRoleAppService;
        private readonly IAdminLoginLogsAppService adminLoginLogsAppService;

        public AuthController(
            IAdminAppService adminAppService,
            IAdminRoleAppService adminRoleAppService,
            IAdminLoginLogsAppService adminLoginLogsAppService)
        {
            this.adminAppService = adminAppService;
            this.adminRoleAppService = adminRoleAppService;
            this.adminLoginLogsAppService = adminLoginLogsAppService;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        [AllowAnonymous]    // [AllowAnonymous]不用经过授权就可以直接访问
        public IActionResult Login()
        {
            return View();
        }

        /// <summary>
        /// 提交登录信息
        /// </summary>
        /// <returns></returns>
        [ActionName("Login")]
        [HttpPost]
        [AllowAnonymous]
        public async Task<IActionResult> PostLogin()
        {
            var account = Request.Form["account"].ToString("");
            var password = Request.Form["confirmPassword"].ToString("");

            if (string.IsNullOrWhiteSpace(account))
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "请填写用户名" });
            }
            if (string.IsNullOrWhiteSpace(password))
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "请填写登录密码" });
            }

            var admin = await adminAppService.BaseFirstOrDefaultAsync(t => t.AdminName == account && t.Status == 0);
            if (admin == null)
            {
                return Json(new AjaxResultDto() { Code = 500, Message = "用户名或密码错误" });
            }

            // 登录日志
            var loginLogs = new AdminLoginLogs()
            {
                CreateTime = DateTime.Now,
                AdminId = admin.Id,
                RefererUrl = Request.GetReferer(),
                Url = Request.GetCurrentUrl(),
                Ip = Request.GetClientIp(),
                Brower = Request.GetClientBrower()
            };

            if (admin.PassWord.ToUpper() != MD5EncryptUtil.MD5Encrypt(password + admin.Salt).ToUpper())
            {
                loginLogs.Message = "密码错误";
                await adminLoginLogsAppService.BaseInsertAsync(loginLogs);

                return Json(new AjaxResultDto() { Code = 500, Message = "用户名或密码错误" });
            }

            if (!string.IsNullOrWhiteSpace(admin.LoginCurrentBrower))
            {
                admin.LoginLastBrower = admin.LoginCurrentBrower;
            }
            if (!string.IsNullOrWhiteSpace(admin.LoginCurrentIp))
            {
                admin.LoginLastIp = admin.LoginCurrentIp;
            }
            if (admin.LoginCurrentTime != DateTime.MinValue)
            {
                admin.LoginLastTime = admin.LoginCurrentTime;
            }

            admin.LoginCurrentBrower = Request.GetClientBrower();
            admin.LoginCurrentIp = Request.GetClientIp();
            admin.LoginCurrentTime = DateTime.Now;
            admin.LoginNum ++;

            admin.UpdateTime = DateTime.Now;
            await adminAppService.BaseUpdateAsync(admin);

            var roleId = 0;
            if (ManageConst.SuperAdminName.Contains(admin.AdminName))
            {
                roleId = ManageConst.SuperRoleId;
            }
            else
            {
                // 角色
                roleId = await adminRoleAppService.GetAdminRoleId(admin.Id);
                if (roleId == 0)
                {
                    loginLogs.Message = "用户没有配置角色";
                    await adminLoginLogsAppService.BaseInsertAsync(loginLogs);

                    return Json(new AjaxResultDto() { Code = 500, Message = "用户没有配置角色" });
                }
            }

            var timestamp = DateTimeUtil.GetTimestamp();

            // 创建 身份验证 Cookie
            var claims = new List<Claim> {
                new Claim(ManageConst_ClaimTypes.Id, admin.Id.ToString()),
                new Claim(ManageConst_ClaimTypes.Name, admin.AdminName),
                new Claim(ManageConst_ClaimTypes.RoleId, roleId.ToString()),
                new Claim(ManageConst_ClaimTypes.ts, timestamp.ToString())
            };

            var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
            // 登录有效期：默认当天
            var expiredTime = DateTimeOffset.Parse($"{DateTimeOffset.Now:yyyy-MM-dd 23:59:59}");

            // 创建加密的 cookie，并将其添加到当前响应中，写入客户端
            await HttpContext.SignInAsync(
                CookieAuthenticationDefaults.AuthenticationScheme,
                new ClaimsPrincipal(claimsIdentity),
                // 设置 Cookie 有效期
                new AuthenticationProperties
                {
                    IsPersistent = true,
                    ExpiresUtc = expiredTime
                });

            // 保存登录状态到 Redis
            bool store = await adminAppService.SetLoginedInfo(admin.Id, timestamp, DateTimeUtil.DifferenTimespan(DateTime.Now, expiredTime));
            if (!store)
            {
                loginLogs.Message = "无法保存登录状态";
                await adminLoginLogsAppService.BaseInsertAsync(loginLogs);

                // 保存失败，退出登录状态，并重定向到 登录页
                await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
                return RedirectToAction("Login");
            }

            loginLogs.Message = "登录成功";
            loginLogs.IsSuccess = true;
            await adminLoginLogsAppService.BaseInsertAsync(loginLogs);

            return Json(new AjaxResultDto() { Message = "登录成功" });
        }

        /// <summary>
        /// 退出登录
        /// </summary>
        /// <returns></returns>
        [DefaultPermission]
        [HttpGet]
        public async Task<IActionResult> Logout()
        {
            // 清除登录 Cookie 信息
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

            // 重定向到 登录页
            return RedirectToAction("Login");
        }
    }
}
